package com.TexasHoldem;

import java.util.List;
import java.util.Set;

import com.TexasHoldem.RpcInterface.rpc.TexasHoldemService;
import com.TexasHoldem.RpcInterface.rpc.TexasHoldemService.ActDataResponse;
import com.TexasHoldem.RpcInterface.rpc.TexasHoldemService.BoardUpdatedResponse;
import com.TexasHoldem.RpcInterface.rpc.TexasHoldemService.CommunityCardsResponse;
import com.TexasHoldem.RpcInterface.rpc.TexasHoldemService.HandResponse;
import com.TexasHoldem.RpcInterface.rpc.TexasHoldemService.PlayerActedDataResponse;
import com.TexasHoldem.RpcInterface.rpc.TexasHoldemService.PlayerEnterResponse;
import com.TexasHoldem.RpcInterface.rpc.TexasHoldemService.PlayerLeaveResponse;
import com.TexasHoldem.RpcInterface.rpc.TexasHoldemService.Response;
import com.TexasHoldem.RpcInterface.rpc.TexasHoldemService.ShowCardsDataResponse;
import com.TexasHoldem.RpcInterface.rpc.TexasHoldemService.TexasHoldem.BlockingInterface;
import com.TexasHoldem.core.Card;
import com.TexasHoldem.core.Player;
import com.TexasHoldem.core.actions.Action;
import com.google.protobuf.BlockingRpcChannel;
import com.google.protobuf.RpcCallback;
import com.google.protobuf.RpcController;
import com.google.protobuf.ServiceException;
import com.google.protobuf.Descriptors.MethodDescriptor;
import com.googlecode.protobuf.socketrpc.RpcChannels;
import com.googlecode.protobuf.socketrpc.RpcForwarder;
import com.googlecode.protobuf.socketrpc.SocketRpcController;
import com.googlecode.protobuf.socketrpc.RpcForwarder.RpcException;
import com.googlecode.protobuf.socketrpc.SocketRpcProtos;
import com.googlecode.protobuf.socketrpc.SocketRpcProtos.ProtocolMessage;
import com.googlecode.protobuf.socketrpc.SocketRpcProtos.Request;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.ReadTimeoutException;

/**
 * @author su
 * 负责管理处理牌桌的请求业务
 */
public class TexasHoldemHandler extends SimpleChannelInboundHandler<SocketRpcProtos.ProtocolMessage> implements ITexasHoldemChannelHandlerContext {

	private final RpcForwarder rpcForwarder;
	private ChannelHandlerContext handlectx;
	
	public TexasHoldemHandler(RpcForwarder rpcForwarder) {
		super();
		this.rpcForwarder = rpcForwarder;
	}

	// 这里是channel 出现异常了就关闭,但是有时候不能捕获到 ClosedChannelException
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
			throws Exception {
		// TODO Auto-generated method stub
		super.exceptionCaught(ctx, cause);
		System.out.print("exceptionCaught" + ctx.channel().toString() + "\n");
		
		
		
//		TexasHoldemService.NotifyMsg.Builder t = TexasHoldemService.NotifyMsg.newBuilder();
//        
//        
//		if(cause.getMessage() == null )
//		{
//			t.setMsg("PlayerNetException");
//		}
//		else
//		{
//			t.setMsg(cause.getMessage());
//		}
//		//服务器自己构造客户端远程调用,实现网络异常事件通知服务器的player
//        
//         
//         com.googlecode.protobuf.socketrpc.SocketRpcProtos.Request.Builder r = com.googlecode.protobuf.socketrpc.SocketRpcProtos.Request.newBuilder();
//         r.setRequestProto(t.build().toByteString());
//         MethodDescriptor methodret = null;
//         for(MethodDescriptor method:com.TexasHoldem.RpcInterface.rpc.TexasHoldemService.TexasHoldem.getDescriptor().getMethods())
//         {
//        	 if(method.getName().equals("PlayerNetException"))
//        		 methodret = method;
//         }
//         r.setMethodName(methodret.getName());
//         r.setServiceName(methodret.getService().getFullName());
//         forwardRpc(r.build(),ctx);
         
         ctx.channel().close();
    
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		// TODO Auto-generated method stub
		super.channelActive(ctx);
		handlectx = ctx;
	}

	private void forwardRpc(SocketRpcProtos.Request rpcRequest,final ChannelHandlerContext cx) {
		// Create callback to pass to the forwarder
		RpcCallback<SocketRpcProtos.Response> rpcCallback = new RpcCallback<SocketRpcProtos.Response>() {
			@Override
			public void run(SocketRpcProtos.Response rpcResponse) {
				
				cx.writeAndFlush(SocketRpcProtos.ProtocolMessage.newBuilder().setResponse(rpcResponse).build());
			}
		};

		// Forward request
		try {
			rpcForwarder.doRpc(rpcRequest, rpcCallback,this.handlectx.channel());
		} catch (RpcException e) {
			e.printStackTrace();
			// sendResponse(handleError(e.msg, e.errorReason, e.getCause()));
		}
	}



	//这里是读写IDLE 触发
	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
			throws Exception {
		// TODO Auto-generated method stub
		if (evt instanceof IdleStateEvent) {
			IdleStateEvent event = (IdleStateEvent) evt;
			if (event.state().equals(IdleState.READER_IDLE)) {
				System.out.println("READER_IDLE" + ctx.channel().toString() + "\n");
			} else if (event.state().equals(IdleState.WRITER_IDLE)) {
				System.out.println("WRITER_IDLE" + ctx.channel().toString() + "\n");
			} else if (event.state().equals(IdleState.ALL_IDLE)) {
				System.out.println("ALL_IDLE" + ctx.channel().toString() + "\n");

			}
		}
		super.userEventTriggered(ctx, evt);
	}

	@Override
	protected void channelRead0(ChannelHandlerContext arg0, ProtocolMessage arg1)
			throws Exception {
		// TODO Auto-generated method stub
		if(arg1.getRequest().isInitialized())
		{
			forwardRpc(arg1.getRequest(),arg0);
		}
		else if(arg1.getResponse().isInitialized())
		{
			
		}
	}

	@Override
	public ChannelHandlerContext get() {
		// TODO Auto-generated method stub
		return this.handlectx;
	}


	
	
}
